home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-2.iso / extra / backgmmn.zip / BACKSCRE.C < prev    next >
C/C++ Source or Header  |  1995-02-24  |  17KB  |  610 lines

  1. /************************************************************************/
  2. /*  Hoser BackGammon version 1.0                    */
  3. /*    Robert Pfister                            */
  4. /*    Rfd#3 Box 2340        home:(207)-873-3520            */
  5. /*    Waterville, Maine 04901                        */
  6. /*                                    */
  7. /*    Pfister_rob%dneast@dec.decwrl                    */
  8. /*                                    */
  9. /*  Copyright  June,1987 all rights reserved.                */
  10. /*                                    */
  11. /*  This program will play a game of backgammon at the novice level    */
  12. /*                                    */
  13. /*  The code is in 4 parts...                        */
  14. /*     1) back.c     - main driver                    */
  15. /*   /   2) eval.c     - evaluation of moves                */
  16. /* \/     3) backscn.c  - screen stuff..                    */
  17. /*     4) backmenu.c - menu stuff, help text, and ``decoder''        */
  18. /*                                    */
  19. /* this was compiled under Manx 3.20a, using long integers        */
  20. /*                                    */
  21. /* This file contains:                            */
  22. /*    gen_points    PutIntuiText    ITextLen    Gsetup        */
  23. /*    ShowDice    PutMoveNumber    PutPiece    decode        */
  24. /*    DoMenuStrip    UndoMenuStrip    requestor    finit        */
  25. /*    PutBarPiece    PutSpike    BlinkPiece    TextScreen    */
  26. /************************************************************************/
  27. /* Most recent modification:     3/ 8/93                */
  28. /* Most recent modification:    11/28/94                */
  29. /* Most recent modification:     2/24/95                */
  30.  
  31. #include <proto/intuition.h>
  32. #include <proto/dos.h>
  33. #include <proto/exec.h>
  34. #include <proto/graphics.h>
  35. #include <proto/intuition.h>
  36. #include <proto/diskfont.h>
  37. #include <clib/alib_protos.h>
  38. #include <stdio.h>
  39. #include <string.h>
  40. #include <stdlib.h>
  41. #include <math.h>
  42. #include "back.h"
  43.  
  44. #define max_vector    16        /* for AreaMove/Draw            */
  45. #define piece_width    32
  46. #define sign(x)        (x < 0 ? -1 : +1)
  47.  
  48. typedef
  49.   struct {
  50.     SHORT    x,y;}    coord;
  51.  
  52. typedef
  53.     /* order of points in box[] is upper left, lower right or        */
  54.     /* left, top, right, bottom as individual values            */
  55.     /* Spike entry is coordinates of spike point                */
  56.   struct {
  57.     coord        box[2];
  58.     coord        spike;} point_rec;
  59. typedef
  60.   struct {
  61.     short    count,
  62.         height;
  63.     coord    point[13];}    shape_rec;
  64.  
  65. static const shape_rec
  66.   laced_piece =
  67.     {12, 23,
  68.     {{ 13,  2}, { 11,  6}, {  4,10}, { -4,10},
  69.      {-11,  6}, {-13,  2}, {-13,-2}, {-11,-6},
  70.      { -4,-10}, {  4,-10}, { 11,-6}, { 13,-2}}},
  71.   norm_piece =
  72.     {12, 11,
  73.     {{ 13, 1}, { 11, 3}, {  3, 5}, { -3, 5},
  74.      {-11, 3}, {-13, 1}, {-13,-1}, {-11,-3},
  75.      { -3,-5}, {  3,-5}, { 11,-3}, { 13,-1}}};
  76. static point_rec    point[26];
  77. int            minY;            /* has to be global        */
  78. static int        xc, yc,            /* center of board        */
  79.             minX, maxX,        /* horizontal limits        */
  80.             /*minY,*/ maxY,        /* vertical limits        */
  81.             h_pitch,        /* width of spike        */
  82.             height,            /* spike height            */
  83.             move_num_left,        /* where move number starts    */
  84.             move_num_len,        /* how long it plots        */
  85.             bar_left, bar_right;    /* limits of bar        */
  86. static  shape_rec    *piece_ptr = &norm_piece;
  87. UWORD            color_table[] =
  88.     {0x407,0xDDD,0x0F0,0xFF0,0xF00,0x000,0x00F,0xEEE};
  89. struct ColorMap        color_map =
  90.     {0,0,sizeof(color_table) / 2,(APTR)&color_table};
  91. char            MyTitle[] =
  92.      "Hoser BackGammon     Copyright June 1987     Robert Pfister";
  93. struct RastPort        *rp;
  94. struct Screen        *screen = NULL;
  95. static struct ViewPort    *vp;
  96. extern struct Menu    MyMenu[];  /* get the menu somewhere else */
  97. struct Window        *w = NULL;
  98. struct TextAttr        font[] = {{"topaz",8,0,0},{"courier.font",13,0,0}};
  99. struct TextFont        *tf = NULL;
  100.  
  101. struct NewScreen    ns = {
  102.     0,0,-1,-1,3, 0,1, HIRES, CUSTOMSCREEN,font, MyTitle, NULL,NULL};
  103. struct  NewWindow    nw = {
  104.     0,10,-1,190,0,1, CLOSEWINDOW | MOUSEBUTTONS | MENUPICK,
  105.     SMART_REFRESH | ACTIVATE | WINDOWDRAG | WINDOWDEPTH, NULL,NULL,
  106.     "Backgammon anyone?", NULL,NULL,  0,0,640,200,CUSTOMSCREEN };
  107. struct  NewWindow    crnw = {
  108.     20,0,405,0,0,1,    /* top and height set when used */
  109.     MOUSEBUTTONS, SMART_REFRESH | ACTIVATE | WINDOWDRAG,
  110.     NULL,NULL, "Backgammon credits", NULL,NULL, 0,0,640,200,CUSTOMSCREEN };
  111. static short        AreaBuf[max_vector * 5 / sizeof(short)];
  112. static APTR        TBuf;
  113. static struct TmpRas    TRas;
  114. static struct AreaInfo    AInfo;
  115. BOOL            laced;
  116.  
  117. void gen_points(struct Window *wp)
  118. {                /* adjust board for screen/window size    */
  119.   int        bar_width,    /* the obvious                */
  120.         d, n;
  121.   point_rec    *prp;
  122.  
  123.   minX = 3;
  124.   maxX = wp->Width - 3;
  125.   bar_width = 8;
  126.   h_pitch = (maxX - minX - bar_width) / 12;
  127.   bar_width = maxX - minX - 12 * h_pitch;
  128.   if (bar_width > 10) {
  129.     minX += (bar_width - 10) / 2;
  130.     maxX -= (bar_width - 10) / 2;
  131.     bar_width = maxX - minX - 12 * h_pitch;
  132.   }
  133.   xc = (minX + maxX) / 2;
  134.   bar_left = xc - bar_width / 2;
  135.   bar_right = bar_left + bar_width;
  136.  
  137.   minY = screen->Font->ta_YSize * 3 + 1;
  138.   maxY = wp->Height - 4;
  139.   height = ((maxY - minY) * 3 / 7);
  140.   yc = (minY + maxY) / 2;
  141.  
  142.   d = 0;
  143.   prp = point + 1;
  144.   for (n = 0; n < 12; n++) {
  145.     prp->box[1].x = (prp->box[0].x = minX + n * h_pitch + d) + h_pitch - 1;
  146.     prp->spike.y  =
  147.     prp->box[0].y = (prp->box[1].y = maxY) - height;
  148.     prp->spike.x  = prp->box[0].x + h_pitch / 2;
  149.     if (n == 5)
  150.       d = bar_width;
  151.     prp++;
  152.   }
  153.  
  154.   for (n = 11; n >= 0; n--) {
  155.     prp->box[1].x = (prp->box[0].x = minX + n * h_pitch + d) + h_pitch - 1;
  156.     prp->box[0].y = minY;
  157.     prp->spike.y  =
  158.     prp->box[1].y = (prp->box[0].y = minY) + height;
  159.     prp->spike.x  = prp->box[0].x + h_pitch / 2;
  160.     if (n == 6)
  161.       d = 0;
  162.     prp++;
  163.   }
  164.  
  165.   prp = point;
  166.   prp->box[0].x = xc - 10;
  167.   prp->box[0].y = maxY - height;
  168.   prp->box[1].x = xc + 10;
  169.   prp->box[1].y = yc + 5;
  170.   prp->spike.x  = xc;
  171.   prp->spike.y  = yc + 9;
  172.  
  173.   prp = point + 25;
  174.   prp->box[0].x = xc - 10;
  175.   prp->box[0].y = maxY + height;
  176.   prp->box[1].x = xc + 10;
  177.   prp->box[1].y = yc - 5;
  178.   prp->spike.x  = xc;
  179.   prp->spike.y  = yc - 9;
  180. }
  181.  
  182. void PutIntuiText(char *s, int x, int y, int color)
  183. {
  184.   struct IntuiText    it = {1, 0, JAM2, 0, 0, NULL, NULL, NULL};
  185.  
  186.   it.FrontPen = color;
  187.   it.LeftEdge = x;
  188.   it.TopEdge = y;
  189.   it.IText = s;
  190.   PrintIText(w->RPort, &it, 0, 0);
  191. }
  192.  
  193. int ITextLen(char *s)
  194. {
  195.   struct IntuiText    it = {1, 0, JAM2, 0, 0, NULL, NULL, NULL};
  196.  
  197.   it.IText = s;
  198.   return IntuiTextLength(&it);
  199. }
  200.  
  201. void Gsetup(void)
  202. {
  203.   struct Preferences    prefs;
  204.  
  205.   GetPrefs(&prefs, sizeof prefs);
  206.   if (laced = (prefs.LaceWB & LACEWB)) {
  207.     ns.ViewModes |= LACE;
  208.     ns.Font = &font[1];
  209.     tf = OpenDiskFont(&font[1]);
  210.     piece_ptr = &laced_piece;
  211.   }
  212.   if (!(nw.Screen = screen = OpenScreen(&ns))) {
  213.     finit();
  214.     Alert(1);
  215.     exit(1);
  216.   }
  217.  
  218.   nw.Width = screen->Width;
  219.   nw.TopEdge = screen->TopEdge + screen->Font->ta_YSize + 2;
  220.   nw.Height = screen->Height - nw.TopEdge;
  221.   if (!(w = OpenWindow(&nw))) {
  222.     finit();
  223.     Alert(2);
  224.     exit(2);
  225.   }
  226.  
  227.   vp = &screen->ViewPort;
  228.   rp = w->RPort;
  229.   /* intialize temporary area space */
  230.   InitArea(&AInfo, AreaBuf, max_vector);
  231.   rp->AreaInfo = &AInfo;
  232.   if (!(TBuf = (APTR)AllocRaster(screen->Width, screen->Height))) {
  233.     finit();
  234.     Alert(3);
  235.     exit(3);
  236.   }
  237.  
  238.   gen_points(w);
  239.   SetMenuStrip(w,MyMenu);
  240.   rp->TmpRas = &TRas;
  241.   InitTmpRas(&TRas, (char *)TBuf, RASSIZE(screen->Width, screen->Height));
  242.   LoadRGB4(vp, color_table, 8);
  243.   SetDrMd(rp, JAM1);
  244.  
  245.   SetAPen(rp, back_color);
  246.   RectFill(rp, minX, minY, maxX - 1, maxY);
  247.  
  248.   SetAPen(rp, tm1_color);
  249.   RectFill(rp, bar_left, minY, bar_right, maxY);
  250.   /* write evaluation count at top of window    */
  251.   move_num_len = ITextLen("Number of Moves Evaluated: ");
  252.   move_num_left = minX + 2 + move_num_len;
  253.   PutIntuiText("Number of Moves Evaluated:", minX + 2,
  254.     minY - screen->Font->ta_YSize - 2, dice_color);
  255.   {
  256.     struct DateStamp    time;
  257.  
  258.     DateStamp(&time);
  259.     srand(time.ds_Tick);
  260.   }
  261. }
  262.  
  263. void ShowDice(BYTE  d[4], int c)
  264. {                    /* put dice on the screen    */
  265.   int            yu, yl;
  266.   char            line[] = "      ";
  267.   struct IntuiText    it = {1, 0, JAM1, 0, 0, NULL, NULL, NULL};
  268.  
  269.   /* cover up dice with dice color */
  270.   yu = yc - screen->Font->ta_YSize / 2;
  271.   yl = yu + screen->Font->ta_YSize;
  272.   SetAPen(rp, dice_color);
  273.   RectFill(rp, xc-27, yu , xc+27, yl);
  274.  
  275.   if (d[0] && d[1]) {
  276.     /* put in the numbers for the left and right die */
  277.     it.FrontPen = piece2_color;
  278.     if (c == Uside)
  279.       it.FrontPen = piece1_color;
  280.     line[0] = '0' + d[0];
  281.     line[4] = '0' + d[1];
  282.     it.LeftEdge = xc - piece_width / 2;
  283.     it.TopEdge = yu + 1;
  284.     it.IText = line;
  285.     PrintIText(w->RPort, &it, 0, 0);
  286.     SetAPen(rp, tm1_color);
  287.     RectFill(rp, bar_left, yu, bar_right - 1, yl);
  288.   }
  289. }
  290.  
  291. void PutMoveNumber(int Number)
  292. { /* only calls are from EVAL */
  293.   char Line[8];
  294.  
  295.   sprintf(Line,"%5d  ",Number);
  296.   PutIntuiText(Line, move_num_left,
  297.     minY - screen->Font->ta_YSize - 2, dice_color);
  298. }
  299.  
  300. void PutPiece(long x, long y, long color)
  301. { /* coords are for center of piece    */
  302.   int        i;
  303.   shape_rec    *sp = piece_ptr;
  304.  
  305.   SetAPen(rp,color);
  306.   AreaMove(rp, x + sp->point[sp->count - 1].x, y + sp->point[sp->count - 1].y);
  307.   for (i = 0; i < sp->count; i++)
  308.     AreaDraw(rp, x + sp->point[i].x, y + sp->point[i].y);
  309.   AreaEnd(rp);
  310. }
  311.  
  312. int decode(int x, int y) /* return the 'spike' number given the screen        */
  313. {             /* point relative to upper left corner of the window    */
  314.   int    point,
  315.     disp = 0,
  316.     font_height = screen->Font->ta_YSize;
  317.  
  318.   if (x > xc)
  319.     disp = bar_right - bar_left;
  320.   /* check if dice 'clicked'...indicate unusual end of turn */
  321.   if ((y > (yc - font_height / 2)) && (y < (yc + font_height / 2)) &&
  322.     (x > xc - 27) && (x < xc + 27))
  323.     return(-1);
  324.   /* check if 'bar' selected */
  325.   if ((x > (xc - piece_width / 2)) && (x < (xc + piece_width / 2))  &&
  326.     ( y > (font_height  - 2 - piece_ptr->height)) &&
  327.     (y < (yc - font_height / 2 - 2)))
  328.     point = 0;
  329.   else
  330.     point = 1 + (x + disp - minX) / h_pitch;
  331.   if ( y < yc)
  332.     point = 25 - point;
  333.   return(point);
  334. }
  335.  
  336. static int ErrSet=FALSE;
  337.  
  338. void DoMenuStrip(char errmsg[])
  339. {
  340.   ErrSet=TRUE;
  341.   SetWindowTitles(w, (char *)-1, errmsg);
  342. }
  343.  
  344. void UnDoMenuStrip(void)
  345. {
  346.   if (ErrSet == TRUE) {
  347.     SetWindowTitles(w, (char *)-1, MyTitle);
  348.     ErrSet = FALSE;
  349.   }
  350. }
  351.  
  352. /* put up a plain old requestor given three strings
  353.     name...    the question/statement of the requestor
  354.     yes...    the affirmative response
  355.     no...    the negative response
  356.     this returns 'true' for the yes, 'false' for the no  */
  357.  
  358. BOOL requestor(char name[], char yes[], char no[])
  359. {
  360.   const static struct IntuiText
  361.     Rt = {tm1_color,    tm2_color,    JAM2, 50, 10, NL, (char *)0, NL},
  362.     Rr = {spike2_color, spike1_color, JAM1,  8,  3, NL, (char *)0, NL};
  363.   struct IntuiText    Rbody, Rright, Rleft;
  364.  
  365.   Rbody = Rt;        Rright = Rr;        Rleft = Rr;
  366.   Rleft.IText = no;    Rright.IText = yes;    Rbody.IText = name;
  367.   return(AutoRequest(w, &Rbody, &Rleft, &Rright, 0, 0, 300, 90));
  368. }
  369.  
  370. extern you_me_rec    you, me;
  371. extern USHORT        total_games;
  372.  
  373. void finit(void)
  374. {
  375.   char    *s[] = {
  376.     "Running totals",
  377.     "\n",
  378.     "\n",
  379.     " Total games xxxxxx\n",
  380.     "                    You          Me\n",
  381.     "   Dice total xxxxxxxxxx  xxxxxxxxxx\n",
  382.     " Average roll       xx.x        xx.x\n",
  383.     "   Incomplete xxxxxxxxxx  xxxxxxxxxx\n",
  384.     "       Wasted xxxxxxxxxx  xxxxxxxxxx\n",
  385.     "\n",
  386.     " [click in window to terminate] \n"};
  387.  
  388.   if (total_games) {
  389.     sprintf(&s[3][13], "%6d\n", total_games);
  390.     sprintf(&s[5][14], "%10d  %10d\n", you.total.roll, me.total.roll);
  391.     sprintf(&s[6][20], "%4.1f        %4.1f\n",
  392.     (float)you.total.average_roll / total_games,
  393.     (float)me.total.average_roll / total_games);
  394.     sprintf(&s[7][14], "%10d  %10d\n", you.total.incomplete, me.total.incomplete);
  395.     sprintf(&s[8][14], "%10d  %10d\n", you.total.wasted, me.total.wasted);
  396.     TextScreen(s, 11);
  397.   }
  398.  
  399.   if (TBuf)    FreeRaster(TBuf, screen->Width, screen->Height);
  400.   if (w)    CloseWindow(w);
  401.   if (screen)    CloseScreen(screen);
  402.   if (laced)    CloseFont(tf);
  403. }
  404.  
  405. void PutBarPiece(int y, int pieces, int inc, int color)
  406. {
  407.   char            line[4];
  408.   struct IntuiText    it = {1, 0, JAM1, 0, 0, NULL, NULL, NULL};
  409.  
  410.   SetAPen(rp, back_color);
  411.   RectFill(rp, xc - piece_width, y, xc + piece_width, y + inc);
  412.   SetAPen(rp, tm1_color);
  413.   RectFill(rp, bar_left, y, bar_right - 1, y + inc);
  414.   pieces = abs(pieces);
  415.   if (pieces != 0) {
  416.     PutPiece(xc, y + inc / 2, color);
  417.     if (pieces > 1) {
  418.       sprintf(line, "%d", pieces);
  419.       it.FrontPen = dice_color;
  420.       it.LeftEdge = bar_left;
  421.       it.TopEdge = y + 2;
  422.       it.IText = line;
  423.       PrintIText(w->RPort, &it, 0, 0);
  424.     }
  425.   }
  426. }
  427.  
  428. void PutSpike(int spk, int pieces)
  429. {
  430.   long    color, inc, x, y;
  431.   char    line[4];
  432.  
  433.   /* pick color of the pieces */
  434.   if (pieces < 0)
  435.     color = piece1_color;
  436.   else
  437.     color = piece2_color;
  438.   inc = - piece_ptr->height;
  439.   if (spk > 12)
  440.       inc = -inc;
  441.  
  442.   if (spk == 0)                /* plot my ones on the bar    */
  443.     PutBarPiece(yc + screen->Font->ta_YSize, pieces, -inc, color);
  444.   else if (spk == 25)            /* plot yours on the bar    */
  445.     PutBarPiece(yc - screen->Font->ta_YSize - inc, pieces, inc, color);
  446.   else {                /* all the rest            */
  447.     int        i;
  448.     point_rec    *pp;
  449.  
  450.     pp = &point[spk];
  451.     /* box in the area around the spike with background color...*/
  452.     SetAPen(rp, back_color);
  453.     RectFill(rp, pp->box[0].x, pp->box[0].y, pp->box[1].x, pp->box[1].y);
  454.  
  455.     if (spk & 1)
  456.       SetAPen(rp, spike1_color);
  457.     else
  458.       SetAPen(rp, spike2_color);
  459.     if (spk < 13) { /* lower spikes */
  460.       AreaMove(rp,pp->box[0].x,pp->box[1].y);    /* lower left corner    */
  461.       AreaDraw(rp,pp->box[1].x,pp->box[1].y);    /* lower right corner    */
  462.       AreaDraw(rp,pp->spike.x,pp->spike.y);    /* point of spike    */
  463.       AreaDraw(rp,pp->box[0].x,pp->box[1].y);    /* lower left corner    */
  464.     AreaEnd(rp);
  465.     }
  466.     else { /* upper spikes */
  467.       AreaMove(rp,pp->box[0].x,pp->box[0].y);    /* upper left corner    */
  468.       AreaDraw(rp,pp->box[1].x,pp->box[0].y);    /* upper right corner    */
  469.       AreaDraw(rp,pp->spike.x,pp->spike.y);    /* point of spike    */
  470.       AreaDraw(rp,pp->box[0].x,pp->box[0].y);    /* upper left corner    */
  471.     AreaEnd(rp);
  472.     }
  473.  
  474.     if (pieces < 0)
  475.       pieces = -pieces;
  476.     /* go through number of pieces, up to "PerSpike" */
  477.     x = pp->spike.x;
  478.     y = pp->box[1].y;
  479.     if (spk > 12)
  480.       y = pp->box[0].y;
  481.     y += inc / 2;
  482.     inc += 2 * sign(inc);
  483.  
  484.     for(i = 0; (i < pieces) && (i < PerSpike); i++) {
  485.       PutPiece(x, y, color);
  486.       y += inc;
  487.     }
  488.     /* put some fancy numbers on it if > PerSpike pieces */
  489.     if (pieces > PerSpike) {
  490.       sprintf(line,"%2d",pieces);
  491.       y = pp->box[1].y - 2;
  492.       if (spk > 12)
  493.     y = pp->box[0].y + 8;
  494.       Move(rp, x - screen->Font->ta_YSize, y);
  495.       SetAPen(rp, dice_color);
  496.       Text(rp, line, 2);
  497.     }
  498.   }
  499. }  /* end of PutSpike */
  500.  
  501. void BlinkPiece(BYTE board[], int pos)
  502. {
  503.   int        x, y, i, color, inc;
  504.   point_rec    *pp;
  505.  
  506.   if (board[pos]) {        /* Don't bother if nothing there    */
  507.     pp = &point[pos];
  508.     x = pp->spike.x;
  509.     inc = piece_ptr->height;
  510.     if ((pos == 0) || (pos == 25))
  511.       y = pp->spike.y;
  512.     else {
  513.       inc = -piece_ptr->height;
  514.       y = pp->box[1].y;
  515.       if (pos > 12) {
  516.     inc = -inc;
  517.     y = pp->box[0].y;
  518.       }
  519.       y += inc / 2;
  520.       y += 2 * sign(inc);
  521.     }
  522.     if ((pos != 0) && (pos != 25))
  523.       y += (min(abs(board[pos]), PerSpike) - 1) * inc;
  524.     color = piece2_color;
  525.     if (board[pos] < 0)
  526.       color = piece1_color;
  527.     for(i = 2; i >= 0; i--) {
  528.       Delay(1);
  529.       switch (pos) {
  530.     case  0:
  531.       PutBarPiece(yc + screen->Font->ta_YSize, board[0], inc, color);
  532.       break;
  533.     case 25:
  534.       PutBarPiece(yc - screen->Font->ta_YSize - inc, board[25], inc, color);
  535.       break;
  536.     default:
  537.       PutPiece(x, y, dice_color);
  538.       }
  539.       Delay(1);
  540.       switch (pos) {
  541.     case  0:
  542.       PutBarPiece(yc + screen->Font->ta_YSize, board[0], inc, color);
  543.       break;
  544.     case 25:
  545.       PutBarPiece(yc - screen->Font->ta_YSize - inc, board[25], inc, color);
  546.       break;
  547.     default:
  548.       PutPiece(x, y, color);
  549.       }
  550.     }
  551.     PutSpike(pos, board[pos]);
  552.   }
  553. }
  554.  
  555. void TextScreen(char *stuff[], int num)
  556. {
  557.   int            i, n, longest = 0;
  558.   unsigned long        Class;
  559.   struct IOStdReq    *wr;
  560.   struct MsgPort    *wrp;
  561.   struct Window        *crw;
  562.   struct IntuiMessage    *message;
  563.   const char        cons_init[] = "\2330 p";
  564.   struct IntuiText    it = {1, 0, JAM1, 0, 0, NULL, NULL, NULL};
  565.  
  566.   for (i = 1; i <= num; i++) {
  567.     it.IText = stuff[i];
  568.     if ((n = IntuiTextLength(&it)) > longest)
  569.       longest = n;
  570.   }
  571.   crnw.Width = min(longest +10, screen->Width);
  572.   crnw.LeftEdge = (screen->Width - crnw.Width) / 2;
  573.   crnw.Height  = (num + 1) * screen->Font->ta_YSize;
  574.   crnw.TopEdge = (maxY - crnw.Height) / 2;
  575.   crnw.Screen  = screen;
  576.   crnw.Title   = stuff[0];
  577.   crw          = (struct Window *)OpenWindow(&crnw);
  578.   if (crw != NULL) {
  579.     wrp = CreatePort("my.con.write",0);
  580.     wr = CreateStdIO(wrp);
  581.     wr->io_Data = (APTR) crw;
  582.     wr->io_Length = sizeof(struct Window);
  583.     if (OpenDevice("console.device", 0, (struct IORequest *)wr, 0) == 0) {
  584.       wr->io_Command = CMD_WRITE;
  585.       wr->io_Length = -1;
  586.       wr->io_Data   = (APTR)cons_init;
  587.       DoIO((struct IORequest *)wr);
  588.       /* loop through all the stuff and put it to the open'd console */
  589.       for (i = 1; i < num; i++) {
  590.     wr->io_Length = -1;
  591.     wr->io_Data   = (APTR)stuff[i];
  592.     DoIO((struct IORequest *)wr);
  593.       }
  594.       /* close the console */
  595.       CloseDevice((struct IORequest *)wr);
  596.       DeleteStdIO(wr);
  597.       DeletePort(wrp);
  598.     }/* end-if console created */
  599.     for (;;) {
  600.       Wait(1L << crw->UserPort->mp_SigBit);
  601.       message = (struct IntuiMessage *) GetMsg(crw->UserPort);
  602.       Class = message->Class;
  603.       ReplyMsg((struct Message *)message);
  604.       if (Class == MOUSEBUTTONS)
  605.     break;
  606.     }
  607.     CloseWindow(crw);
  608.   }  /* end-if window opened */
  609. }
  610.